﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.ComponentModel.DataAnnotations;

namespace Toolkit.Web.Mvc.Validation
{
    /// <summary>
    /// A base class for validators that have attributes that require and an additional property to check for validity.
    /// Note: Registration of these attributes is required.
    /// 
    /// Ex. (In Global.asax.cs -> Application_Start())
    /// DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(NameOfAttribute), typeof(NameOfAttributeModelValidator));
    /// </summary>
    /// <typeparam name="TAttribute">The type of the attribute.</typeparam>
    public abstract class DependentFieldModelValidator<TAttribute> : DataAnnotationsModelValidator<TAttribute>
        where TAttribute : ValidationAttribute, IDependentFieldModelValidationAttribute
    {
        /// <summary>
        /// Initializes a new instance of the DependentFieldModelValidator class.
        /// </summary>
        /// <param name="metadata">Description of the model being validated.</param>
        /// <param name="context">The controller context.</param>
        /// <param name="attribute">The attribute being validated.</param>
        protected DependentFieldModelValidator(ModelMetadata metadata, ControllerContext context, TAttribute attribute)
            : base(metadata, context, attribute)
        {
        }

        /// <summary>
        /// Returns a list of validation error messages for the model.
        /// </summary>
        /// <param name="container">The container for the model.</param>
        /// <returns>A list of validation error messages for the model, or an empty list if no errors have occurred.</returns>
        public override IEnumerable<ModelValidationResult> Validate(object container)
        {
            IDependentFieldModelValidationAttribute attribute = Attribute as IDependentFieldModelValidationAttribute;

            if (!attribute.IsValid(ControllerContext, container, Metadata))
            {
                yield return new ModelValidationResult()
                {
                    Message = ErrorMessage
                };
            }
        }
    }
}
